package com.kly.chatter.api.application.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.StringUtils;
import com.kly.chatter.api.application.dto.UserCodeRequest;
import com.kly.chatter.api.application.service.BaseService;
import com.kly.chatter.api.application.service.ChatterModelInfoExamineService;
import com.kly.chatter.api.application.utils.ChatterHttpUtils;
import com.kly.sc.api.application.annos.SignIgnore;
import com.kly.sc.api.application.annos.VisitorAccessible;
import com.kly.sc.api.application.constant.ApiRedisKeys;
import com.kly.sc.api.application.enums.ApiResultStatus;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.utils.JwtUtils;
import com.kly.sc.api.infras.exception.ApplicationException;
import com.kly.service.UserVasPurchasesService;
import com.kly.user.chatterService.ChatterUserService;
import com.kly.user.chatterService.GreetingService;
import com.kly.user.constant.RedisKey;
import com.kly.user.dto.UserAccessDto;
import com.kly.user.dto.UserInfoDto;
import com.kly.user.dto.UserMsgDto;
import com.kly.user.dto.chatter.ChatterLogin;
import com.kly.user.dto.chatter.request.AlbumsRequestDto;
import com.kly.user.dto.chatter.response.ImagesDto;
import com.kly.user.dto.chatter.response.UserGreetingContentDto;
import com.kly.user.enums.*;
import com.kly.user.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(value = "chatter操作类", tags = {"chatter操作类"})
@RestController
@RequestMapping("chatter")
public class UserController {

    private final static Logger logger = LoggerFactory.getLogger(UserController.class);


    @NacosValue(value = "${chatter.api.userUrl}", autoRefreshed = true)
    private String apiUrl;
    @Resource
    RedisClient redisClient;
    @Resource
    UserAlbumsContentService userAlbumsContentService;
    @Resource
    UserMsgService userMsgService;
    @Resource
    UserService userService;
    @Resource
    BaseService baseService;
    @Resource
    ChatterUserService chatterUserService;
    @Resource
    GreetingService greetingService;
    @Resource
    AuthLoginService authLoginService;

    @Resource
    OtherService otherService;

    @Resource
    private UserVasPurchasesService userVasPurchasesService;


    @Autowired
    private ChatterModelInfoExamineService chatterModelInfoExamineService;

    private static final Integer ONE = 1;

    private static final Integer ZERO = 1;

    @ApiOperation("登陆")
    @RequestMapping(value = "/login", method = {RequestMethod.POST})
    @SignIgnore
    @VisitorAccessible
    @SentinelResource
    public Response authLogin(@Valid @RequestBody ChatterLogin chatterLogin, BindingResult results) throws IOException {
        if (results.hasErrors()) {
            throw new ApplicationException(ApiResultStatus.ACCOUNT_OR_PASSWORD_EMPTY);
        }
        String ssl = ChatterHttpUtils.toPost(
                apiUrl + "chatter/user/authLogin", BeanUtil.beanToMap(chatterLogin));
        if (StringUtils.isNotEmpty(ssl)) {
            JSONObject jsonObject = JSONUtil.parseObj(ssl);
            if (jsonObject.getStr("userCode") != null) {
                UserInfoDto userInfoDto = JSONUtil.toBean(ssl, UserInfoDto.class);
                if (userInfoDto.getStatus() == UserStatus.INIT.getType() || userInfoDto.getStatus() == UserStatus.CLOSE.getType()) {
                    return Response.error(ResultStatus.ACCOUNT_SUSPENDED);
                }
                String token = JwtUtils.generateToken(userInfoDto.getUserCode(), null, true);
                redisClient.set("key_{}_{}", token, RememberTime.ONE_YEAR.getTime(),
                        userInfoDto.getUserCode(), RedisKey.TOKEN_CODE);
                UserAccessDto userAccessDto = new UserAccessDto();
                userAccessDto.setToken(token);
                userAccessDto.setUserCode(userInfoDto.getUserCode());
                authLoginService.saveToken(userAccessDto, UserTokenType.SYSTEM_TOKEN);
                return Response.ok(userAccessDto);
            } else if (jsonObject.getStr("status") != null) {
                int status = Integer.parseInt(jsonObject.getStr("status"));
                // 5 账号不存在
                // 6 密码错误
                if (status == 5) {
                    return Response.error(ResultStatus.ACCOUNT_NOT_FOUND);
                } else if (status == 6) {
                    return Response.error(ResultStatus.INCORRECT_PASSWORD);
                }
            }
        }

        return Response.error(ResultStatus.USER_NOT_EXIST);
    }

    @ApiOperation("用户信息")
    @ResponseBody
    @RequestMapping(value = "/userProfile", method = {RequestMethod.POST})
    @SentinelResource
    public Response getUserByUserCode(@RequestBody UserCodeRequest request, BindingResult results) {

        if (results.hasErrors()) {
            return Response.error(ResultStatus.MISSING_USER_INFORMATION,
                    results.getAllErrors().get(0).getDefaultMessage());
        }

        // 确定用户编码，如果请求中没有提供则默认为当前用户的编码

        // 获取用户信息
        Response<UserInfoDto> userInfoResponse = userService.getUserByUserCode(request.getUserCode());
        if (userInfoResponse.isSuccess() && userInfoResponse.getData() != null) {
            Response<List<UserGreetingContentDto>> listResponse =
                    greetingService.queryByModelUserCode(request.getUserCode());
            if (listResponse.isSuccess() && CollUtil.isNotEmpty(listResponse)) {
                userInfoResponse.getData().setHasGreetingFlag(ONE);
            }
            boolean dealStatus = chatterModelInfoExamineService.dealStatus(request.getUserCode());
            userInfoResponse.getData().setAbountMeStatus(dealStatus ? 1 : 0);
        }

        return userInfoResponse;
    }


    /**
     * 查询图片消息
     *
     * @param albumsRequest
     * @param results
     * @return
     */
    @ApiOperation("查询图片消息")
    @RequestMapping(value = "/getImage", method = {RequestMethod.POST})
//    @SignIgnore
    @VisitorAccessible
    @SentinelResource
    public Response getImage(@Valid @RequestBody AlbumsRequestDto albumsRequest, BindingResult results) {
        if (results.hasErrors()) {
            throw new ApplicationException(ApiResultStatus.PARAMETER_VALIDATION_FAILED);
        }
        //获取chatUserCode
        String chatUserCode = RequestLocalInfo.getCurrentUser().getUserCode();
        //判断查询相册的用户权限
        boolean modeUserCode = baseService.getModeUserCode(chatUserCode, albumsRequest.getUserCode());
        if (!modeUserCode) {
            throw new ApplicationException(ApiResultStatus.NO_PERMISSION_TO_VIEW_ALBUM);
        }

        String userCode = albumsRequest.getUserCode();
        String toUserCode = albumsRequest.getToUserCode();

        // 消息数少于10条，不允许发送照片
        boolean unavailable = false;
        String redisKey = ApiRedisKeys.UNLOCK_TO_SEND_PRIVATE_ALBUM.getValue();
        if (redisClient.get(redisKey, userCode, toUserCode) != null) {
            unavailable = true;
        } else {
            List<UserMsgDto> userMsg = userMsgService.selectByFromUserAndToUser(toUserCode, userCode, ONE);
            if (CollUtil.isNotEmpty(userMsg)) {
                UserMsgDto msg = userMsg.get(0);
                logger.info("User message from {} to {}: {}", toUserCode, userCode, JSONUtil.parseObj(msg));
                unavailable = msg.getId() >= 10;
            }
        }

        if (unavailable) {
            redisClient.set(redisKey, true, RememberTime.ONE_DAY.getTime(), userCode, toUserCode);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("userCode", userCode);
        map.put("unavailable", unavailable);
        List<ImagesDto> privateContent = null;

        if (albumsRequest.getAlbumType() == AlbumsType.PRIVATE_ALBUMS.getType()) {
            privateContent =
                    userAlbumsContentService.getPrivateContent(userCode, albumsRequest.getAlbumType());
            if (CollUtil.isNotEmpty(privateContent)) {
                logger.info("privateContent:{}", JSONUtil.toJsonStr(privateContent));
                //未查看相册
                Map<String, String> notViewAlbums = redisClient.hGetAll(ApiRedisKeys.NOT_VIEWED_PRIVATE_ALBUM.getValue(),
                        userCode, toUserCode);
                //已查看相册
                Map<String, String> viewAlbums = redisClient.hGetAll(ApiRedisKeys.VIEW_PRIVATE_ALBUMS.getValue(),
                        userCode, toUserCode);
                // 遍历 privateContent 列表
                for (ImagesDto image : privateContent) {
                    image.setSendToUserFlag(false);
                    image.setUnlocked(false);
                    String imageCode = image.getImageUrl();
                    String notViewedDateStr = notViewAlbums.get(imageCode);
                    String viewedDateStr = viewAlbums.get(image.getImageCode());
                    // 判断是否在 notViewAlbums 中存在
                    image.setSendFlag(true);
                    if (notViewedDateStr != null) {
                        processImage(false, image, notViewedDateStr);
                    }
                    // 判断是否在 viewAlbums 中存在
                    else if (viewedDateStr != null) {
                        processImage(true, image, viewedDateStr);
                    } else {
                        //判断是否解锁
                        int unLockCount = userVasPurchasesService.getUnlockCount(toUserCode, userCode, image.getImageCode());
                        if (unLockCount > 0) {
                            image.setSendToUserFlag(true);
                            image.setUnlocked(true);
                        } else {
                            //判断是否发送
                            Response<Boolean> response = otherService.sendImageStatus(userCode, toUserCode, image.getImageCode());
                            if (response.isSuccess()) {
                                if (response.getData()) {
                                    image.setSendToUserFlag(true);
                                    image.setUnlocked(false);
                                }
                            }
                        }
                    }
                }
            }

        } else if (albumsRequest.getAlbumType() == (AlbumsType.PUBLIC_ALBUMS.getType())) {
            Map<String, Object> prams = new HashMap<>();
            prams.put("modelUserCode", userCode);
            prams.put("userCode", toUserCode);
            prams.put("type", AlbumsType.PUBLIC_ALBUMS.getType());
            privateContent =
                    userAlbumsContentService.getPrivateContent(prams);

            logger.info("publicContent:{}", JSONUtil.parseObj(privateContent));
            map.put("unavailable", true);

            //是否已发送
            if (privateContent != null) {
                privateContent.forEach(entry -> {
                    Response<Boolean> response = otherService.sendImageStatus(albumsRequest.getUserCode(), albumsRequest.getToUserCode(), entry.getImageCode());
                    if (response.isSuccess()) {
                        entry.setSendToUserFlag(response.getData());
                    }
                });
            }
        }
        map.put("images", privateContent);
        return Response.ok(map);
    }

    private void processImage(boolean Viewed, ImagesDto image, String dateStr) {
        Date date = DateUtil.parse(dateStr);
        // 检查是否超过当前时间
        if (date.after(DateUtil.date())) {
            long seconds = DateUtil.between(DateUtil.date(), date, DateUnit.SECOND);
            image.setUnlocked(Viewed); // 设置未解锁标志
            image.setDeadlineTime(seconds); // 设置剩余时间（秒数）
            image.setSendToUserFlag(true);
        } else {
            image.setSendToUserFlag(true);
        }
    }



    @ApiOperation("添加用户操作记录")
    @RequestMapping("/storeEventLog/{userCode}")
    @SentinelResource
    @VisitorAccessible
    public Response storeEventLog(@PathVariable("userCode") String userCode) {
        return chatterUserService.storeEventLog(userCode, "null", 0L);
    }

}
